package ru.ifmo.tanya;

import org.apache.log4j.BasicConfigurator;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import ru.ifmo.tanya.core.calls.Dispatcher;
import ru.ifmo.tanya.db.DataBaseManager;
import ru.ifmo.tanya.handler.ServiceHandler;
import ru.ifmo.tanya.handler.StaticHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;


public class CallCenterServer {

    private static int PORT = 8069;

    private static final int MIN_THREADS = Runtime.getRuntime().availableProcessors();
    private static final int MAX_THREADS = MIN_THREADS * 10;

    private Server jettyServer;

    private static final String SERVICE_TARGET_PREFIX = "/service";

    private static String startServer() {
        CallCenterServer server = new CallCenterServer();
        try {
            server.init();
            server.start();
            InetAddress localhost = InetAddress.getLocalHost();
            return "http://" + localhost.getHostAddress() + ":" + PORT;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private void start() throws Exception {
        jettyServer.start();
    }

    private void init() {
        QueuedThreadPool queuedThreadPool = new QueuedThreadPool(MAX_THREADS);
        queuedThreadPool.setName("GladiolusServerPool");
        queuedThreadPool.setMinThreads(MIN_THREADS);

        jettyServer.setThreadPool(queuedThreadPool);
        jettyServer.setHandler(new HandlerProvider());
        jettyServer.setStopAtShutdown(true);

        System.setErr(System.out);
    }

    private static class HandlerProvider extends AbstractHandler {

        private ServiceHandler serviceHandler;
        private StaticHandler staticHandler;

        public HandlerProvider() {
            serviceHandler = new ServiceHandler();
            staticHandler = new StaticHandler();
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            if (target.startsWith(SERVICE_TARGET_PREFIX)) {
                serviceHandler.handle(target, baseRequest, request, response);
            } else {
                staticHandler.handle(target, baseRequest, request, response);
            }
        }
    }

    public CallCenterServer() {
        jettyServer = new Server(PORT);
    }

    public static void main(String[] args) {
        BasicConfigurator.configure();
        DataBaseManager.getJdbcTemplate();
        startServer();
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Dispatcher().startMonitoring();
            }
        }).start();
    }
}
